package com.kxxnzstdsw.utils

import com.github.benmanes.caffeine.cache.*
import kotlinx.coroutines.runBlocking
import java.util.concurrent.TimeUnit

/**本地缓存工具类*/
object CaffeineUtils {
  /**
   * 手动加载
   * @param duration 时间
   * @param timeUnit 单位
   * @param max 最大缓存条数
   * */
  fun <K, V> cache(duration: Long = 10, timeUnit: TimeUnit = TimeUnit.MINUTES, max: Long = 10000): Cache<K, V> =
    Caffeine.newBuilder()
      .expireAfterWrite(duration, timeUnit)
      .maximumSize(max)
      .build()

  /**
   * 自动加载
   * @param duration 时间
   * @param timeUnit 单位
   * @param max 最大缓存条数
   * @param loading 获取缓存数据的方法
   * */
  fun <K, V> loadingCache(
    duration: Long = 10,
    timeUnit: TimeUnit = TimeUnit.MINUTES,
    max: Long = 10000,
    loading: suspend (K) -> V
  ): LoadingCache<K, V> = Caffeine.newBuilder()
    .maximumSize(max)
    .expireAfterWrite(duration, timeUnit)
    .build {
      runBlocking {
        loading(it)
      }
    }

  /**
   * 手动异步加载
   * @param duration 时间
   * @param timeUnit 单位
   * @param max 最大缓存条数
   * */
  fun <K, V> asyncCache(
    duration: Long = 10,
    timeUnit: TimeUnit = TimeUnit.MINUTES,
    max: Long = 10000,
  ): AsyncCache<K, V> = Caffeine.newBuilder()
    .expireAfterWrite(duration, timeUnit)
    .maximumSize(max)
    .buildAsync()


  /**
   * 自动异步加载
   * @param duration 时间
   * @param timeUnit 单位
   * @param max 最大缓存条数
   * @param loading 获取缓存数据的方法
   * */
  fun <K, V> asyncLoadingCache(
    duration: Long = 10,
    timeUnit: TimeUnit = TimeUnit.MINUTES,
    max: Long = 10000,
    loading: (K) -> V
  ): AsyncLoadingCache<K, V> = Caffeine.newBuilder()
    .maximumSize(10000)
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .buildAsync(loading)
}

